/*
 *  Copyright 2003 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *  
 */
/*
 *  ======== osdutil.c ========
 */

#include <std.h>
#include <csl_cache.h>
#include <osdutil.h>
#include <osdcolor.h>
#include <tsk.h>            

static Uint8 fontData[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// space                   
	0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00,// exclamation point
	0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// quotation mark          
	0x00, 0x50, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x50, 0x00, 0x00,// number sign             
	0x00, 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20, 0x00, 0x00,// dollar sign             
	0x00, 0x48, 0xA8, 0x50, 0x20, 0x50, 0xA8, 0x90, 0x00, 0x00,// percent sign            
	0x00, 0x60, 0x90, 0xA0, 0x40, 0xA8, 0x90, 0x68, 0x00, 0x00,// ampersand               
	0x30, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// apostrophe              
	0x10, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x10, 0x00,// left parenthesis        
	0x40, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x40, 0x00,// right parenthesis       
	0x00, 0x00, 0x50, 0x70, 0xD8, 0x70, 0x50, 0x00, 0x00, 0x00,// asterisk                
	0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00, 0x00,// plus sign               
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x20, 0x40, 0x00,// comma                   
	0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,// hyphen-minus            
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, 0x20, 0x00,// period                  
	0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00,// forward slash           
	0x00, 0x20, 0x50, 0x88, 0xA8, 0x88, 0x50, 0x20, 0x00, 0x00,// digit zero              
	0x00, 0x20, 0x60, 0xA0, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,// digit one               
	0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8, 0x00, 0x00,// digit two               
	0x00, 0xF8, 0x08, 0x10, 0x30, 0x08, 0x88, 0x70, 0x00, 0x00,// digit three             
	0x00, 0x30, 0x50, 0x50, 0x90, 0xF8, 0x10, 0x10, 0x00, 0x00,// digit four              
	0x00, 0xF8, 0x80, 0xF0, 0x88, 0x08, 0x88, 0x70, 0x00, 0x00,// digit five              
	0x00, 0x70, 0x88, 0x80, 0xF0, 0x88, 0x88, 0x70, 0x00, 0x00,// digit six               
	0x00, 0xF8, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00,// digit seven             
	0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70, 0x00, 0x00,// digit eight             
	0x00, 0x70, 0x88, 0x88, 0x78, 0x08, 0x88, 0x70, 0x00, 0x00,// digit nine              
	0x00, 0x00, 0x20, 0x70, 0x20, 0x00, 0x20, 0x70, 0x20, 0x00,// colon                   
	0x00, 0x00, 0x20, 0x70, 0x20, 0x00, 0x30, 0x20, 0x40, 0x00,// semicolon               
	0x00, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00,// less-than sign          
	0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,// equals sign             
	0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,// greater-than sign       
	0x00, 0x70, 0x08, 0x10, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00,// question mark           
	0x00, 0x30, 0x48, 0x98, 0xA8, 0x98, 0x40, 0x30, 0x00, 0x00,// at sign                 
	0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x00, 0x00,// capital letter A        
	0x00, 0xE0, 0x90, 0x90, 0xF0, 0x88, 0x88, 0xF0, 0x00, 0x00,// capital letter B        
	0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00, 0x00,// capital letter C        
	0x00, 0xE0, 0x90, 0x88, 0x88, 0x88, 0x90, 0xE0, 0x00, 0x00,// capital letter D        
	0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8, 0x00, 0x00,// capital letter E        
	0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x00,// capital letter F        
	0x00, 0x70, 0x88, 0x80, 0x98, 0x88, 0x88, 0x70, 0x00, 0x00,// capital letter G        
	0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x00, 0x00,// capital letter H        
	0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00,// capital letter I        
	0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00,// capital letter J        
	0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88, 0x00, 0x00,// capital letter K        
	0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8, 0x00, 0x00,// capital letter L        
	0x00, 0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88, 0x00, 0x00,// capital letter M        
	0x00, 0x88, 0xC8, 0xC8, 0xA8, 0x98, 0x98, 0x88, 0x00, 0x00,// capital letter N        
	0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00,// capital letter O        
	0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x00,// capital letter P        
	0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x70, 0x18, 0x00,// capital letter Q        
	0x00, 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88, 0x00, 0x00,// capital letter R        
	0x00, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70, 0x00, 0x00,// capital letter S        
	0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,// capital letter T        
	0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00,// capital letter U        
	0x00, 0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00, 0x00,// capital letter V        
	0x00, 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xD8, 0x88, 0x00, 0x00,// capital letter W        
	0x00, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00, 0x00,// capital letter X        
	0x00, 0x88, 0x88, 0x88, 0x70, 0x20, 0x20, 0x20, 0x00, 0x00,// capital letter Y        
	0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00, 0x00,// capital letter Z        
	0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, 0x00,// left square bracket     
	0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00,// backslash               
	0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00,// right square bracket    
	0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// circumflex              
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00,// underscore              
	0x60, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// grave accent            
	0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78, 0x00, 0x00,// small letter a          
	0x00, 0x80, 0x80, 0xB0, 0xC8, 0x88, 0xC8, 0xB0, 0x00, 0x00,// small letter b          
	0x00, 0x00, 0x00, 0x70, 0x88, 0x80, 0x88, 0x70, 0x00, 0x00,// small letter c          
	0x00, 0x08, 0x08, 0x68, 0x98, 0x88, 0x98, 0x68, 0x00, 0x00,// small letter d          
	0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78, 0x00, 0x00,// small letter e          
	0x00, 0x30, 0x48, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x00, 0x00,// small letter f          
	0x00, 0x00, 0x00, 0x68, 0x98, 0x88, 0x98, 0x68, 0x08, 0x70,// small letter g          
	0x00, 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88, 0x00, 0x00,// small letter h          
	0x00, 0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,// small letter i          
	0x00, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,// small letter j          
	0x00, 0x80, 0x80, 0x90, 0xA0, 0xE0, 0x90, 0x88, 0x00, 0x00,// small letter k          
	0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x30, 0x00, 0x00,// small letter l          
	0x00, 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0xA8, 0x88, 0x00, 0x00,// small letter m          
	0x00, 0x00, 0x00, 0xB0, 0xC8, 0x88, 0x88, 0x88, 0x00, 0x00,// small letter n          
	0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00,// small letter o          
	0x00, 0x00, 0x00, 0xB0, 0xC8, 0x88, 0xC8, 0xB0, 0x80, 0x80,// small letter p          
	0x00, 0x00, 0x00, 0x68, 0x98, 0x88, 0x98, 0x68, 0x08, 0x08,// small letter q          
	0x00, 0x00, 0x00, 0xB0, 0xC8, 0x80, 0x80, 0x80, 0x00, 0x00,// small letter r          
	0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0, 0x00, 0x00,// small letter s          
	0x00, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x48, 0x30, 0x00, 0x00,// small letter t          
	0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 0x00, 0x00,// small letter u          
	0x00, 0x00, 0x00, 0x88, 0x88, 0x50, 0x50, 0x20, 0x00, 0x00,// small letter v          
	0x00, 0x00, 0x00, 0x88, 0xA8, 0xA8, 0xA8, 0x50, 0x00, 0x00,// small letter w          
	0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x00,// small letter x          
	0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 0x08, 0x70,// small letter y          
	0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00, 0x00,// small letter z          
	0x18, 0x20, 0x20, 0x20, 0xC0, 0x20, 0x20, 0x20, 0x18, 0x00,// left curly brace        
	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,// vertical bar            
	0xC0, 0x20, 0x20, 0x20, 0x18, 0x20, 0x20, 0x20, 0xC0, 0x00,// right curly brace       
	0x00, 0x48, 0xA8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// tilde                   
	0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00 // rectangle               
};
                                                               
static OSDUTIL_Font fontDefault = {
    OSDUTIL_FONT_DEFAULT_WIDTH, 
    OSDUTIL_FONT_DEFAULT_HEIGHT,
    fontData
};


/*  ======== OSDUTIL_drawPixmap ========
 */
void OSDUTIL_drawPixmap
(
	Uint8 *pFrame,				// pointer to OSD pixel frame
	Uint32 pitch,				// Line-to-line pitch, expressed in pixels
	OSDUTIL_Point *loc,			// pixmap final resting location
	OSDUTIL_PixMap *pPixmap,	// pointer to pixmap
	Uint8 fgColor,				// Foreground color (i.e. on pixel color)
	Uint8 bgColor				// Background color (i.e. off pixel color)
)
{
	int x, y;
	Uint8 *pDst, *pSrc, data;
	Uint8 pixColor;

	pFrame += (loc->y * pitch) + loc->x; // move to start of drawing area
	pSrc = pPixmap->data;
	for (y = 0; y < pPixmap->height; y++) {
		pDst = pFrame;
		for (x = 0; x < pPixmap->width; x++) {
			if ((x & 7) == 0)
				data = *pSrc++;
			pixColor = (data & 0x80) ? fgColor : bgColor;
			if (pixColor != OSDCOLOR_NODRAW)
				*pDst++ = pixColor;
			else
				pDst++;
			data <<= 1;
		}
		pFrame += pitch;
	}
}

/*  ======== OSDUTIL_line ========
 */

void OSDUTIL_line(Uint8* buf, OSDUTIL_Point* a, OSDUTIL_Point* b, Int color, Int bufWidth)
{
    Int xDelta = b->x - a->x;
    Int yDelta = b->y - a->y;
    Int seed = 0;            
    Int curX, curY;
    Int xInc = xDelta > 0 ? 1: -1;
    Int yInc = yDelta > 0 ? 1: -1;

    
    xDelta *= xInc;
    yDelta *= yInc;
    if(xDelta == 0) xInc = 0;
    if(yDelta == 0) yInc = 0;        
    if(xDelta >= yDelta) {
        curX = a->x;
        curY = a->y;
        do {
            buf[curY * bufWidth + curX] = color;
            curX += xInc;
            seed += yDelta;
            if(seed >= xDelta) {
                curY += yInc;
                seed -= xDelta;
            }
        }while(curX != b->x );
    }else{
        curX = a->x;
        curY = a->y;
        do {
            buf[curY * bufWidth + curX] = color;
            curY += yInc;
            seed += xDelta;
            if(seed >= yDelta) {
                curX += xInc;
                seed -= yDelta;
            }
        }while(curY != b->y );
    }                           
}

/*  ======== OSDUTIL_rectangle ========
 * Draw a colored rectangle in the OSD buffer.
 */
void OSDUTIL_rectangle(
	Uint8 *buf,					// buffer pointer
	OSDUTIL_Point* topLeft,				// top left coordinate for rectangle
	OSDUTIL_Point* bottomRight,			// bottom right coordinate for rectangle
	Int color,				// color fill index value
	Int bufWidth				// buffer pitch (width)
)
{
    int i, j;   

    for(i = 0; i < bottomRight->y - topLeft->y + 1; i ++ ){    
        for(j = 0; j < bottomRight->x - topLeft->x + 1; j ++ ){    
            buf[topLeft->x + (topLeft->y + i) * bufWidth + j] = color; 
        }
    }
}


/*  ======== OSDUTIL_text ========
 * Display a text string in an OSD pixel frame at the given X/Y location
 * (expressed in pixels from top left of the frame).  The character bounding
 * box is coded in the font information. fgColor and bgColor indicate the
 * foreground and background color respectively of the drawn character(s),
 * with one exception: if either is specified as OSDCOLOR_NODRAW, the pixel
 * will not be drawn, but will be left as-is.  Note that this is different
 * from a transparent color, which is specified by setting the MSBit of the
 * color byte (OSDCOLOR_TRANSPARENT).
 */
void OSDUTIL_text(
	Uint8 *pFrame,				// pointer to the OSD pixel frame
	Uint32 pitch,				// Line-to-line pitch, expressed in pixels
	OSDUTIL_Point* loc,					// Location of first character
	char *pString,				// Pointer to ASCII string to be shown
	OSDUTIL_Font *font,					// Font to use
	Uint8 fgColor,				// Foreground color (i.e. on pixel color)
	Uint8 bgColor)				// Background color (i.e. off pixel color)
{
	Uint32 charSize;
	Uint32 stringSize;
	Uint8 data;
	Uint32 i, j, k;
	Uint8 *p;
	Uint8 pixColor;
	char c;

	if(font == OSDUTIL_FONT_DEFAULT) {
	    font =  &fontDefault;
	}
	stringSize = strlen(pString);		// see how long the string is
	if (stringSize == 0)
		return;

	charSize = (font->fontWidth + 7) >> 3; // number of bytes per horz scan line

	pFrame += (loc->y * pitch) + loc->x; // move to start of string
	for (i = 0; i < font->fontHeight; i++) {
		p = pFrame;
		for (j = 0; j < stringSize; j++) {
			c = pString[j];
			c = (c < ' ') ? 0 : c - ' ';
			for (k = 0; k < font->fontWidth; k++) {
				if ((k & 7) == 0)
					data = font->fontData[(c * font->fontHeight + i) * charSize + (k >> 3)];
				pixColor = (data & 0x80) ? fgColor : bgColor;
				if (pixColor != OSDCOLOR_NODRAW) {
					*p++ = pixColor;
					*p++ = pixColor;
				} else
					p+=2;				// don't draw these pixels
				data <<= 1;				// next pixel in current scan line
			}
			//p+=2;						// two more for inter-character spacing
		}
		pFrame += pitch;
		p = pFrame;
		for (j = 0; j < stringSize; j++) {
			c = pString[j];
			c = (c < ' ') ? 0 : c - ' ';
			for (k = 0; k < font->fontWidth; k++) {
				if ((k & 7) == 0)
					data = font->fontData[(c * font->fontHeight + i) * charSize + (k >> 3)];
				pixColor = (data & 0x80) ? fgColor : bgColor;
				if (pixColor != OSDCOLOR_NODRAW) {
					*p++ = pixColor;
					*p++ = pixColor;
				} else
					p+=2;				// don't draw these pixels
				data <<= 1;				// next pixel in current scan line
			}
			//p+=2;						// two more for inter-character spacing
		}
		pFrame += pitch;
	}
}

